import { IDashboardStore } from '@/core/interface/widgets/store';
import { DECtrlController } from './de-ctrl-controller';
import {
	DashboardActionType,
	IAbility,
	ICtrlActionResult,
	IDashboardAbility,
	IDashboardController,
	IDashboardControllerParams,
	IEvent,
	IMDCtrlAbility,
	IParam,
	IViewLogicInput,
} from '../../interface';
import { deepCopy } from '@/core/utils';

/**
 * 数据看板部件控制器
 *
 * @export
 * @class DashboardController
 * @extends {WidgetsController<IDashboardStore>}
 * @implements {IDashboardController}
 * @template T
 */
export class DashboardController
	extends DECtrlController<
		DashboardActionType,
		IDashboardStore,
		IDashboardAbility
	>
	implements IDashboardController<IDashboardStore, IDashboardAbility>
{
	/**
	 * Creates an instance of DashboardController.
	 * @param {IDashboardControllerParams<DashboardActionType, IDashboardAbility>} params
	 * @memberof DashboardController
	 */
	public constructor(
		params: IDashboardControllerParams<DashboardActionType, IDashboardAbility>
	) {
		super(params);
		this.ctrlInit(params);
	}

	/**
	 * 处理部件初始化
	 *
	 * @protected
	 * @param {IDashboardControllerParams<DashboardActionType, IDashboardAbility>} params
	 * @memberof DashboardController
	 */
	protected processCtrlInit(
		params: IDashboardControllerParams<DashboardActionType, IDashboardAbility>
	) {
		super.processCtrlInit(params);
		this.initPortletArray();
	}

	/**
	 * 门户部件数组
	 *
	 * @private
	 * @type {any[]}
	 * @memberof DashboardController
	 */
	private portletArray: any[] = [];

	/**
	 * 初始化门户部件数组
	 *
	 * @memberof DashboardController
	 */
	protected initPortletArray() {
		const { portletArray } = this.model;
		this.portletArray.push(...portletArray);
	}

	/**
	 * 设置子能力
	 *
	 * @param {string} name
	 * @param {IAbility} subAbility
	 * @memberof DashboardController
	 */
	public setSubAbility(name: string, subAbility: IAbility) {
		this.subAbilityCenter.set(name, subAbility);
		if (this.subAbilityCenter.size == this.portletArray.length) {
			this.load();
			this.evt.emit('ctrlInit', this.name, this.getAbility());
		}
	}

	/**
	 * 加载子部件
	 *
	 * @memberof DashboardController
	 */
	public load(opts: IParam = {}): Promise<ICtrlActionResult> {
		return new Promise((resolve: any, reject: any) => {
			const promiseArray: any = [];
			this.portletArray.forEach((item: any) => {
				const ability = this.getPortletCtrlAbility(item.name.toLowerCase());
				if (ability) {
					const promise = ability.load(opts);
					promiseArray.push(promise);
				}
			});
			const { context } = this.store;
			const tempContext = deepCopy(context);
			//
			Promise.all(promiseArray)
				.then((resArray: any) => {
					let _data: any = [];
					resArray.forEach((response: any, resIndex: number) => {
						if (!response || !response.ok) {
							return;
						}
						_data.push(response.rowData);
					});
					let result = { ok: true, rowData: _data };
					resolve(result);
				})
				.catch((response: any) => {
					reject(response);
				});
		});
	}

	/**
	 * 获取门户部件能力
	 *
	 * @protected
	 * @return {*}  {(IMDCtrlAbility)}
	 * @memberof DashboardController
	 */
	protected getPortletCtrlAbility(name: string): IMDCtrlAbility {
		return this.getSubAbility<IMDCtrlAbility>(name);
	}

	/**
	 * 处理门户部件
	 *
	 * @param {IEvent<string>} actionParam
	 * @memberof DashboardController
	 */
	public handleComponentAction(actionParam: IEvent<string>): void {
		const { name, action, data } = actionParam;
		switch (action) {
			case 'portletAction':
				this.handlePortletUIAction(data.event, data.logic);
				break;
		}
	}

	/**
	 * 处理portlet界面行为
	 *
	 * @param {MouseEvent} event 事件源
	 * @param {IViewLogicInput} logic 逻辑
	 * @memberof DashboardController
	 */
	private handlePortletUIAction(
		event: MouseEvent,
		logic: IViewLogicInput
	): void {
		const { context, viewParams } = this.store;
		App.getViewLogicHelper().executeViewLogic(
			context,
			viewParams,
			this.getData(),
			event,
			this.getAbility(),
			logic
		);
	}

	/**
	 * @description 获取能力
	 * @return {*}  {IDashboardAbility}
	 * @memberof DashboardController
	 */
	public getAbility(): IDashboardAbility {
		return {
			...super.getAbility(),
			load: this.load.bind(this),
		};
	}
}
